/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: Dec 31, 2009
 * Time: 10:35:55 AM
 * To change this template use File | Settings | File Templates.
 */
import java.util.*;
import org.jdom.Element;

// Referenced classes of package dk.brics.dsd:
//            Rule, AttributeField, ChardataField, Field,
//            FieldEvaluationException, Context, Schema, Boolexp,
//            Validator

class PointerRule extends Rule
{

    PointerRule(Element element, Schema schema)
    {
        fields = new ArrayList();
        Iterator iterator = element.getChildren().iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            Element element1 = (Element)iterator.next();
            if(Schema.isDSDElement(element1))
                if(element1.getName().equals("attributefield"))
                    fields.add(new AttributeField(element1, schema));
                else
                if(element1.getName().equals("chardatafield"))
                    fields.add(new ChardataField(element1, schema));
                else
                    exp = Boolexp.parse(element1, schema);
        } while(true);
        key = element.getAttributeValue("key");
        if(key == null)
            key = "";
    }

    void checkPointers(Context context, Map map, Element element)
    {
        boolean flag = false;
        ArrayList arraylist = new ArrayList();
        arraylist.add(key);
        for(Iterator iterator = fields.iterator(); iterator.hasNext();)
            try
            {
                String s = ((Field)iterator.next()).evaluate(context, element);
                arraylist.add(s);
            }
            catch(FieldEvaluationException fieldevaluationexception)
            {
                context.v.invalid2(context, "pointer field evaluation failed at element " + Validator.getElementName(context.e) + ", " + fieldevaluationexception.getMessage(), toXML(context));
                flag = true;
            }

        if(flag)
            return;
        Set set = (Set)map.get(arraylist);
        Validator.debug("found " + (set != null ? set.size() : 0) + " nodes matching fields " + arraylist);
        if(set == null)
        {
            context.v.invalid2(context, "pointer check failed at element " + Validator.getElementName(context.e) + " with key value " + arraylist.subList(1, arraylist.size()) + ", destination not found", toXML(context));
            return;
        }
        if(exp != null)
        {
            HashSet hashset = new HashSet();
            Iterator iterator1 = set.iterator();
            do
            {
                if(!iterator1.hasNext())
                    break;
                Element element1 = (Element)iterator1.next();
                if(exp.evaluateMemo(new Context(element1, context.e, context.v)) != 1)
                    hashset.add(element1);
            } while(true);
            Validator.debug("removing " + hashset.size() + " candidates");
            set.removeAll(hashset);
        }
        if(set.size() == 0)
        {
            context.v.invalid2(context, "pointer check failed at element " + Validator.getElementName(context.e) + " with key value " + arraylist.subList(1, arraylist.size()) + ", destination not found", toXML(context));
            return;
        }
        if(set.size() > 1)
        {
            context.v.invalid2(context, "pointer check failed at element " + Validator.getElementName(context.e) + " with key value " + arraylist.subList(1, arraylist.size()) + ", multiple destinations", toXML(context));
            return;
        } else
        {
            Validator.debug(context.e + " -> " + set.iterator().next());
            return;
        }
    }

    Element toXML(Context context)
    {
        Element element = new Element("pointer", "http://www.brics.dk/DSD/2.0");
        if(key != null)
            element.setAttribute("key", key);
        if(exp != null)
            element.addContent(exp.toXML(context));
        for(Iterator iterator = fields.iterator(); iterator.hasNext(); element.addContent(((Field)iterator.next()).toXML(context)));
        return element;
    }

    Boolexp exp;
    List fields;
    String key;
}

